package com.atom.module.document.helper;

import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.media.ExifInterface;

import com.atom.module.logger.Logger;

import java.io.File;
import java.io.IOException;


/**
 * All rights Reserved, Designed By www.rongdasoft.com
 *
 * @version V1.0
 * @Title: BitmapHelper
 * @Description:
 * @author: wuyongzheng
 * @date: 2022/4/1
 * @Copyright: 2022/4/1 www.rongdasoft.com Inc. All rights reserved.
 */
public class BitmapHelper {

    public static Bitmap convertBmp(Bitmap bmp, boolean recycle) {
        int w = bmp.getWidth();
        int h = bmp.getHeight();

        Matrix matrix = new Matrix();
        matrix.postScale(-1, 1); // 镜像水平翻转
        try {
            Bitmap bitmap = Bitmap.createBitmap(bmp, 0, 0, w, h, matrix, true);
            if (null != bitmap && bitmap != bmp) {
                if (recycle && !bmp.isRecycled()) {
                    bmp.recycle();
                }
                bmp = bitmap;
            }
        } catch (Exception e) {
            Logger.e(e);
        }
        return bmp;
    }

    public static Bitmap rotateBitmap(Bitmap b, int degrees, boolean recycle) {
        if (null == b || degrees == 0) {
            return b;
        }
        Matrix m = new Matrix();
        m.setRotate(degrees);
        try {
            Bitmap b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, true);
            if (null != b2 && b != b2) {
                if (recycle && !b.isRecycled()) {
                    b.recycle();
                }
                b = b2;
            }
        } catch (OutOfMemoryError e) {
            Logger.e(e);
        }

        return b;
    }

    public static Bitmap scaleBitmap(Bitmap bitmap, int minLength, boolean recycle) {
        int bitmapW = bitmap.getWidth();
        int bitmapH = bitmap.getHeight();
        float percentage = Math.max(bitmapW, bitmapH) / (float) Math.min(bitmapW, bitmapH);
        int maxLength = (int) (minLength * percentage);
        int scaledWidth = bitmapW > bitmapH ? maxLength : minLength;
        int scaledHeight = bitmapH > bitmapW ? maxLength : minLength;
        try {
            Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, true);
            if (scaledBitmap != null && scaledBitmap != bitmap) {
                if (recycle && !bitmap.isRecycled()) {
                    bitmap.recycle();
                }
                bitmap = scaledBitmap;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bitmap;
    }

    public static Bitmap scaleBitmap(Bitmap bitmap, float percentage, boolean recycle) {
        if (percentage > 0 && percentage < 1) {
            int minLength = Math.min(bitmap.getWidth(), bitmap.getHeight());
            int minResult = (int) (minLength * percentage);
            return scaleBitmap(bitmap, minResult, recycle);
        }
        return bitmap;
    }

    public static Bitmap squareCutBitmap(Bitmap bitmap) {
        int bitmapW = bitmap.getWidth();
        int bitmapH = bitmap.getHeight();
        int maxSide = Math.max(bitmapH, bitmapW);
        int side = Math.min(bitmapH, bitmapW);
        float sp = ((maxSide - side) / 2f) / maxSide;
        return cutBitmap(bitmap, bitmapW > bitmapH ? sp : 0, bitmapW > bitmapH ? 0 : sp, false, side, side, false);
    }

    public static Bitmap cutBitmap(Bitmap bitmap, float x, float y,
                                   boolean isProportion, int offX, int offY,
                                   boolean recycle) {
        if (x < 0 || x > 1) return bitmap;
        if (y < 0 || y > 1) return bitmap;
        int bitmapW = bitmap.getWidth();
        int bitmapH = bitmap.getHeight();
        // top left point x (0 - 1)
        int pointX = (int) (bitmapW * x);
        int pointY = (int) (bitmapH * y);

        int surplusX = bitmapW - pointX;
        int surplusY = bitmapH - pointY;

        if (surplusX < offX || surplusY < offY) {
            if (surplusY >= offY) {
                if (isProportion) {
                    offY = (int) (offY * (surplusX / (float) offX));
                }
                offX = surplusX;
            } else if (surplusX >= offX) {
                if (isProportion) {
                    offX = (int) (offX * (surplusY / (float) offY));
                }
                offY = surplusY;
            } else {
                offX = surplusX;
                offY = surplusY;
            }
        }

        int lastPointX = pointX + offX;
        int lastPointY = pointY + offY;
        try {
            Bitmap result = Bitmap.createBitmap(bitmap, pointX, pointY, lastPointX, lastPointY);
            if (result != null && result != bitmap) {
                if (recycle && !bitmap.isRecycled()) {
                    bitmap.recycle();
                }
                bitmap = result;
            }
        } catch (Exception e) {
            Logger.e(e);
        }
        return bitmap;
    }

    public static Bitmap centerSquareScaleBitmap(Bitmap bitmap, int edgeLength) {
        if (null == bitmap || edgeLength <= 0) {
            return null;
        }
        StringBuilder builder = new StringBuilder();
        builder.append("edgeLength=").append(edgeLength).append(" \n");
        Bitmap result = bitmap;
        int widthOrg = bitmap.getWidth();
        int heightOrg = bitmap.getHeight();
        builder.append("widthOrg=").append(widthOrg).append(" ");
        builder.append("heightOrg=").append(heightOrg).append(" \n");

        if (widthOrg > edgeLength && heightOrg > edgeLength) {
            //压缩到一个最小长度是edgeLength的bitmap
            int longerEdge = (int) (edgeLength * Math.max(widthOrg, heightOrg) / Math.min(widthOrg, heightOrg));
            builder.append("longerEdge=").append(longerEdge).append(" \n");
            int scaledWidth = widthOrg > heightOrg ? longerEdge : edgeLength;
            int scaledHeight = widthOrg > heightOrg ? edgeLength : longerEdge;

            builder.append("scaledWidth=").append(scaledWidth).append(" ");
            builder.append("scaledHeight=").append(scaledHeight).append(" \n");
            Bitmap scaledBitmap;

            try {
                scaledBitmap = Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, true);
            } catch (Exception e) {
                return null;
            }

            //从图中截取正中间的正方形部分。
            int xTopLeft = (scaledWidth - edgeLength) / 2;
            int yTopLeft = (scaledHeight - edgeLength) / 2;

            builder.append("xTopLeft=").append(xTopLeft).append(" ");
            builder.append("yTopLeft=").append(yTopLeft).append(" \n");
            Logger.e(builder.toString());
            try {
                result = Bitmap.createBitmap(scaledBitmap, xTopLeft, yTopLeft, edgeLength, edgeLength);
                scaledBitmap.recycle();

            } catch (Exception e) {
                return null;
            }
        }
        return result;
    }


    /**
     * 获取照片旋转角度
     */
    public static int getExifRotation(String imagePath) {
        int rotate = 0;
        try {
            File imageFile = new File(imagePath);
            ExifInterface exif = new ExifInterface(imageFile.getAbsolutePath());
            int orientation = exif.getAttributeInt(
                ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_NORMAL);

            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_270:
                    rotate = 270;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    rotate = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_90:
                    rotate = 90;
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return rotate;
    }

    public static void saveExifRotation(String path, int degrees) throws IOException {
        ExifInterface exifInterface = new ExifInterface(path);
        int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
        int orientationDegrees = (typeToRotation(orientation) + degrees) % 360;
        exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(rotationToType(orientationDegrees)));
        exifInterface.saveAttributes();
    }

    private static int typeToRotation(int type) {
        switch (type) {
            case ExifInterface.ORIENTATION_ROTATE_270:
                return 270;
            case ExifInterface.ORIENTATION_ROTATE_180:
                return 180;
            case ExifInterface.ORIENTATION_ROTATE_90:
                return 90;
            default:
                return 0;
        }
    }

    private static int rotationToType(int rotation) {
        switch (rotation) {
            case 270:
                return ExifInterface.ORIENTATION_ROTATE_270;
            case 180:
                return ExifInterface.ORIENTATION_ROTATE_180;
            case 90:
                return ExifInterface.ORIENTATION_ROTATE_90;
            default:
                return ExifInterface.ORIENTATION_NORMAL;
        }
    }
}
